/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.wikimark;

import java.io.PrintWriter;
import java.util.Arrays;

final class Statistics {
	private final int[] threads;
	private final int requests;
	private final int[][] throughputs;
	private static final String SEPARATOR = ", ";
	
	Statistics(int[] threads, int requests) {
		this.threads = threads;
		this.requests = requests;
		throughputs = new int[requests][threads.length];
	}
	
	void add(int curThreads, int curRequest, int throughput) {
		throughputs[curRequest][Arrays.binarySearch(threads, curThreads)]
		              = throughput;
	}
	
	void doCSVOut(PrintWriter out) {
		printHeader(out);
		printTable(out);
		out.flush();
	}

	private void printTable(PrintWriter out) {
		for (int request = 0; request < requests; request++) {
			printLineWithMax(out, Integer.toString(request + 1),
					throughputs[request]);
		}
		printAveragesWithMax(out);
		printSeparator(out);
	}

	private void printAveragesWithMax(PrintWriter out) {
		if (requests < 3) {
			return;
		}
		int[] threadAverage = new int[threads.length];
		int[] threadScale = new int[threads.length];
		for (int threadsInd = 0; threadsInd < threads.length; threadsInd++) {
			int min = Integer.MAX_VALUE;
			for (int request = 1; request < requests; request++) {
				threadAverage[threadsInd] += 
					throughputs[request][threadsInd];
				min = Math.min(min, throughputs[request][threadsInd]);
			}
			threadAverage[threadsInd] -= min;
			threadAverage[threadsInd] /= requests - 2;
			threadScale[threadsInd] = threadAverage[threadsInd]
					/ threadAverage[0]; 
		}
		
		printLineWithMax(out, "unbiased average", threadAverage);
	}

	private void printSeparator(PrintWriter out) {
		for (int k = 0; k < threads.length; k++) {
			out.print(SEPARATOR);
		}
		out.println(SEPARATOR + SEPARATOR);
	}

	private void printLineWithMax(PrintWriter out, String firstCol, int[] arr) {
		out.print(firstCol + SEPARATOR);
		int max = 0;
		for (int i = 0; i < arr.length; i++) {				
			max = Math.max(max, arr[i]);
			out.print(arr[i] + SEPARATOR);
		}
		out.println(max + SEPARATOR);
	}

	private void printHeader(PrintWriter out) {
		out.print("request" + SEPARATOR);
		for (int k = 0; k < threads.length; k++) {
			out.print("threads = " + threads[k] + SEPARATOR);
		}
		out.println("Max" + SEPARATOR);
	}
}
